#include <sys/select.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/time.h>
#include <time.h>
#include <string.h>
#include <sys/types.h> // Some integer types
#include <sys/socket.h> // socket structures, address families
#include <unistd.h>
#include <netinet/in.h> //Internet socket address structure
#include <arpa/inet.h>
#include <stdbool.h>
#include <signal.h>
#include <pthread.h>
#include <semaphore.h>
#include <netinet/tcp.h>

/* Tipos de NIPC */
#define HANDSHAKE 		0x00
#define FAIL 			0x01
#define PPD 			0x02
#define PRAID 			0x03
#define PFS 			0x04
#define GETSECTOR 		0x10
#define RTASECTOR 		0x11
#define WRITESECTOR 	0x12
#define WRITESECTOROK   0x13
#define PPDCERRADO	    0x15
#define WRITESINCRO	    0x50
#define SINCROFINISHED  0x51
//Definir si sera necesario un FAIL por cada Accion. (Multithreading)


/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
								ESTRUCTURAS
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
typedef struct ST_PRAID{
	char	szIp[16];
	int		iPuerto;
	int		iFlag;
	int		iSinc;
} __attribute__ ((packed)) ST_PRAID;

typedef uint8_t ST_SECTOR[512];

typedef struct ST_NIPC{
    unsigned char     ucType;
    long             lPayload;
//    char            szPayload[600];
    int                 sector;
    ST_SECTOR           buffer;

} __attribute__ ((packed)) ST_NIPC;

/*typedef struct ST_RESPUESTA{
   unsigned char       ucType;
   int                 sector;
   ST_SECTOR           buffer;
} __attribute__ ((packed)) ST_RESPUESTA;
*/

typedef struct ListaPPD {

			char ppdid[5];
			int  sincronized;
			uint32_t cantSectores;
			unsigned long carga;
			uint16_t socket;
			struct ListaPPD *next;

} __attribute__ ((packed)) lPPd;

lPPd *ptrPPD = NULL;

typedef struct ListaPedPFS{

			ST_NIPC stCab;
			char ppdid[5];
			int sockPPD;
			int sockPFS;
			int estado;
			struct ListaPedPFS *next;

} __attribute__ ((packed)) lPFS;

lPFS *ptrPFS = NULL;

// typedef struct ListaPedWritePFS{

			// ST_NIPC stCab;
			// ST_RESPUESTA stResp;
			// struct ListaPedWritePFS *next;

// } __attribute__ ((packed)) lWritePFS;

//lWritePFS *ptrWritePFS = NULL;


/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
							VARIABLES GLOBALES
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/

ST_PRAID		stPRAID;
//int sockPFS;
int enSincro;		// flag para saber si el praid esta sincronizando
